<template>
    <div>
        <h2>演示计算属性</h2>

        <h3>第1次执行</h3>
        <p> computed: {{ reversedMessage }}</p>
        <p> methods: {{ reversedMessageInMethods() }}</p>

        <h3>第2次执行</h3>
        <p> computed: {{ reversedMessage }}</p>
        <p> methods: {{ reversedMessageInMethods() }}</p>

        <h3>调用次数</h3>
        <p> computed: {{ computedCallTimes }}</p>
        <p> methods: {{ methodCallTimes }}</p>
        <p> methods: {{ callTimes.method }} hack</p>
        <p> message: {{ message }}</p>
    </div>
</template>
<script>
    export default {
        data () {
            return {
                message: 'Hello World',
                computedCallTimes: 0,
                methodCallTimes: 0,
                callTimes: {

                }
            }
        },
        /**
         * 计算属性
         */
        computed: {
            /**
             * 计算属性是有缓存的，只有当计算属性所依赖的数据发生变化时，才会重新取值
             * 比 methods 中的方法效率更好
             * @returns {string}
             */
            reversedMessage: function () {
                // `this` 指向 vm 实例
                console.log("执行了computed reversedMessage");
                this.computedCallTimes ++;
                return this.message.split('').reverse().join('')
            }
        },
        methods: {
            /**
             * 用于与计算属性进行对比
             * @returns {string}
             */
            reversedMessageInMethods() {
                console.log("执行了reversedMessageInMethods");
                /**
                 * 不要在这里更新this.methodCallTimes的值，
                 * 否则，因为修改了属性，系统会不断触发渲染,导致此方法调用多次
                 * 这个例子可多达204次
                 */
                //this.methodCallTimes ++;

                /**
                 * 这种hack方式的统计调用次数有效
                 */
                this.increaseMethodTimes();

                return this.message.split('').reverse().join('')
            },
            /**
             * 因为在data中的 callTimes 初始状态时并没有 method 这个属性
             * vue不会把 method 纳入观察范围内，method的更新不会引起视图的重新渲染
             */
            increaseMethodTimes() {
                if(!this.callTimes.method) {
                    this.callTimes.method = 0;
                }
                this.callTimes.method ++;
            }
        }
    }
</script>